/*
	Codename: Calla
TODO:
  1.Design an fundamentally basic Instruction Set Collection(ISC)
  2.Build a program that can executes these byte-codes directly
  3.Build a compiler

*/
#pragma once
#include <stdint.h>
#include "ca_config.h"
#include "li_collections.h"

// Instruction set collection
// InsCode, args index
typedef struct Li_Ins_t
{
	uint16_t ins;
	uint16_t args;
} Li_Ins_t;
typedef Li_Ins_t *Li_Ins;

// @deprecated
typedef struct
{
	uint32_t loop_count;
	Li_Ins loop_lr;
} LoopControlBlock_t;
typedef LoopControlBlock_t *LoopControlBlock;

typedef struct
{
	Li_List cmds, funs, vars;
} LocalsEnv_t;
typedef LocalsEnv_t *LocalsEnv;

// Stack Frame
typedef struct Li_SF_t
{
	int pageSize;		// the size of current Stack Frame
	Li_Ins lr, entry;	// last PC
	struct Li_SF_t *ls; // last Stack Frame
	int loop_count;		// specifically for 'loop' statement
	LocalsEnv_t locals;
	int argn;
	Any argv;
} Li_SF_t;
typedef Li_SF_t *Li_SF;

// TODO: for-while-loop control block union; Stack Frame designation
// Control Block
typedef struct Li_CB_t
{
	Li_Ins pc;
	int32_t rtc;
	const char *txt;
	const char *erMsg;
	Li_SF sp;
} Li_CB_t;
typedef Li_CB_t *Li_CB;

// Not used: S(end_for),S(if_greater),S(ldr),S(ldrf),S(add),  S(ldrr),  S(ldrfr),
#define __SYSINS__ 	S(ans),S(reg),S(for), S(continue), S(break),\
 					S(cal), S(if), S(regn),S(loop), S(cmd),		\
  					S(goto), S(set),S(setu), S(ldr), S(index), S(call), \
					S(return ), S(end), S(if_not), S(cs), S(frt)

#define S(x) _##x
typedef enum ISCode
{
	__SYSINS__
} ISCode;
int _run_instruction(Li_CB cb, Any args_array[]);
int run_from_bytes_block(int *codes, Li_CB cb);
int _run_instruction_all(Li_CB cb, Any args_array[]);
int disassemble(Li_List _ins, Li_List _args);
int disassemble_from_bytes_block(int *codes);

#undef S
